package com.base.data.tools;

import android.content.ContentValues;
import android.text.TextUtils;


import androidx.annotation.NonNull;

import com.base.common.model.bean.KeyValue;
import com.base.common.utils.JavaMethod;
import com.base.data.annotations.TableField;
import com.base.data.annotations.TableId;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SqlStringJointUtils {

    public static <T> int deleteById(@NonNull T bean) {
        Class cls = bean.getClass();
        KeyValue<String, String, String> keyValue = SqliteUtils.getTabIdField(bean);
        if (keyValue != null) {
            return SqliteUtils.delete(cls, SqliteUtils.toSQLNameDefault(keyValue.getKey()), keyValue.getValue());
        }
        return 0;
    }

    public static <T> int deleteBy(@NonNull Class<?> clas, @NonNull String key, @NonNull String keyValues) {
        return SqliteUtils.delete(clas, SqliteUtils.toSQLNameDefault(key), keyValues);
    }

    public static int delete(@NonNull Class<?> clas, String key, String keyValues) {
        ContentValues values = new ContentValues(1);
        values.put("is_del", 2);
        int count=SqliteUtils.update(SqliteUtils.toTabNameDefault(clas), values, SqliteUtils.toSQLNameDefault(key), keyValues);

        return count;
    }

    public static void clearAll(@NonNull String tabName) {
        String sql = " delete from " + tabName;
        SqliteUtils.getSugarDb().getReadableDatabase().execSQL(sql);
    }

    public static <T> long insert(@NonNull T bean) {
        Class<?> type = bean.getClass();
        Field[] fields = type.getDeclaredFields();
        ContentValues values = new ContentValues(fields.length);
        String tabName = SqliteUtils.toTabNameDefault(type);
        try {
            Field field_id = null;
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.isAnnotationPresent(TableId.class)) {
                    field_id = field;
                }

                if (field.isAnnotationPresent(TableField.class)) {
                    TableField tableField = field.getAnnotation(TableField.class);
                    if (!tableField.exist()) continue;
                }

                Object obj = field.get(bean);
                if (obj != null) {
                    values.put(SqliteUtils.toSQLNameDefault(field), obj.toString());
                }
            }

            long id = SqliteUtils.insert(tabName, values);
            if (id != -1) {
                if (field_id != null) {
                    field_id.set(bean, id);
                }
                return id;
            }

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        return -1;
    }


    public static long insert(@NonNull Map<String, Object> map, @NonNull String tabName) {
        ContentValues values = new ContentValues(map.size());
        for (String s : map.keySet()) {
            Object value = map.get(s);
            if (value != null) {
                values.put(s, value.toString());
            }
        }


        return SqliteUtils.insert(tabName, values);
    }

    /**
     * 按照{@link TableId}标注的属性进行更新数据  所有不为空的数据更新
     *
     * @param bean
     * @param <T>
     * @return
     */
    public static <T> int updateId(@NonNull T bean) {

        Class<?> type = bean.getClass();
        Field[] fields = type.getDeclaredFields();
        ContentValues values = new ContentValues(fields.length);
        String idFieldName = null;
        String idValue = null;
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.isAnnotationPresent(TableId.class)) {
                    idFieldName = SqliteUtils.toSQLNameDefault(field);

                    Object obj = field.get(bean);
                    if (obj != null) {
                        idValue = obj.toString();
                    }
                } else {
                    if (field.isAnnotationPresent(TableField.class)) {
                        TableField tableField = field.getAnnotation(TableField.class);
                        if (!tableField.exist()) continue;
                    }


                    Object obj = field.get(bean);
                    if (obj != null) {
                        values.put(SqliteUtils.toSQLNameDefault(field), obj.toString());
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (TextUtils.isEmpty(idFieldName) || TextUtils.isEmpty(idValue)) return -1;
        return SqliteUtils.updateId(type, values, idFieldName, idValue);
    }

    public static <T> int update(@NonNull T bean, @NonNull String key, @NonNull String keyValues) {
//        if (TextUtils.isEmpty(key) || TextUtils.isEmpty(keyValues)) return 0;

        Class<?> type = bean.getClass();
        Field[] fields = type.getDeclaredFields();
        ContentValues values = new ContentValues(fields.length);

        String tabName = SqliteUtils.toTabNameDefault(type);
        key = SqliteUtils.toSQLNameDefault(key);

        try {
            for (Field field : fields) {

                if (field.isAnnotationPresent(TableField.class)) {
                    TableField tableField = field.getAnnotation(TableField.class);
                    if (!tableField.exist()) continue;
                }

                field.setAccessible(true);
                Object obj = field.get(bean);
                if (obj != null) {
                    values.put(SqliteUtils.toSQLNameDefault(field), obj.toString());
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return SqliteUtils.update(tabName, values, key, keyValues);
    }

    public static <T> T findById(@NonNull Class<T> type, @NonNull String idName, @NonNull String idValue) {
        if (TextUtils.isEmpty(idName) || TextUtils.isEmpty(idValue)) return null;

        String tabName = SqliteUtils.toTabNameDefault(type);
        idName = SqliteUtils.toSQLNameDefault(idName);
        String sql = "select * from " + tabName + " where " + idName + " = " + idValue;

        List<T> list = SqliteUtils.rawQuery(type, sql);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }


    //查寻一条数据
    public static <T> T selectOne(@NonNull T bean) {

        List<T> list = select(bean);
        if (list.size() > 0) {
            return list.get(0);
        }

        return null;
    }

    /**
     * @param bean 所有的属性都必须是对像，不空null的属性都是条件,int 转换成Integer
     * @param <T>
     * @return
     */
    public static <T> List<T> select(@NonNull T bean) {
        Class<T> cls = (Class<T>) bean.getClass();

        List<String> list_where = new ArrayList<>();
        Field[] fields = cls.getDeclaredFields();
        try {
            for (Field field : fields) {

                if (field.isAnnotationPresent(TableField.class)) {
                    TableField tableField = field.getAnnotation(TableField.class);
                    if (!tableField.exist()) continue;
                }

                field.setAccessible(true);
                Object value = field.get(bean);
                if (value != null) {
                    String counName = SqliteUtils.toSQLNameDefault(field);
                    String str = counName + "='" + value.toString() + "'";
                    list_where.add(str);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        String where = " where ";

        if (list_where.size() > 0) {
            where += JavaMethod.join(" and ", list_where);
        } else {
            where = "";
        }


        StringBuffer sql = new StringBuffer();
        sql.append("select * from ");
        sql.append(SqliteUtils.toTabNameDefault(cls));
        sql.append(where);


        return SqliteUtils.rawQuery(cls, sql.toString());
    }

    /**
     * @param cls
     * @param where 是否含有条件    where is_del=1       表示没有删除的字段
     * @return
     */
    public static int selectAllCount(@NonNull Class<?> cls, String... where) {
        return SqliteUtils.selectAllCount(cls, where);
    }

//    public static <T> int selectAllCount(@NonNull T bean) {
//        String where = " ";
//        try {
//            for (Field field : bean.getClass().getDeclaredFields()) {
//                field.setAccessible(true);
//                Object value = field.get(bean);
//                if (value != null) {
//
//                }
//            }
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return SqliteUtils.selectAllCount(bean.getClass(), where);
//    }

    public static <T> List<T> selectAll(@NonNull Class<T> cls, @NonNull String tabName, String where) {
        return selectAll(cls, tabName, where, 0, 0);
    }

    public static <T> List<T> selectAll(@NonNull Class<T> cls, String where) {
        return selectAll(cls, SqliteUtils.toTabNameDefault(cls), where);
    }

    public static <T> List<T> selectAll(@NonNull Class<T> cls, String where, int pn, int ps) {
        return selectAll(cls, SqliteUtils.toTabNameDefault(cls), where, pn, ps);
    }

    public static <T> List<T> selectAll(@NonNull Class<T> cls, @NonNull String tabName, String where, int pn, int ps) {
        if (where == null) where = "";
        String limit = "";
//        where = "";
        String sql = "select * from " + tabName + " " + where;


        if (pn > 0 && ps > 0) {
            limit = " limit " + ps + " offset " + ps * (pn - 1);
        }

        return SqliteUtils.rawQuery(cls, sql + limit);
    }

}
